home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.4d7 source
/
tn3270
/
hndkbd.c
< prev
next >
Wrap
Text File
|
1992-04-17
|
25KB
|
1,058 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.4d7 April, 1992
* Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#if !defined(USEDUMP)
#include "maclib.h"
#include "termdef.h"
#include "tn3270funcs.h"
#include "globals.h"
#else
#pragma load "tn3270DumpFile"
#endif
#pragma segment 3270seg2
#define IAC 255 /* interpret as command: */
#define EOR 239 /* end of record (transparent mode) */
void hndkbd(unsigned char chr, unsigned char shift, cnr *cp)
{
register unsigned char c;
register unsigned char typ, val, geflag, alphaflag;
char paste;
c = chr; /* get character */
/* define type, value, and geflag for key */
typ = kbtyp[c];
alphaflag = geflag = 0;
if (typ & 0x80) geflag = 1;
if (typ & 0x40) alphaflag = 1;
typ &= 0x3f;
if (cp->aplmode) val = kbapl[c];
else {
val = kbstd[c];
if ((val == 0xad) || (val == 0xbd)) geflag = 1;
else geflag = 0;
}
/* check if key should be ignored */
if (val == 0) return;
/* check for pasted character */
if (shift == 99) {
shift = 0;
paste = 1;
}
else {
paste = 0;
}
/* check if alpa lock needs to be applied */
if (alphaflag && shift) val += 0x40;
/* process key based on type code */
switch(typ) {
case 1: datakey(val, geflag, paste, cp);
break;
case 2: attnkey(val, paste, cp);
break;
case 3: funckey(val, paste, cp);
break;
default: break;
}
}
void datakey(unsigned char val, unsigned char geflag, char paste, cnr *cp)
{
register short attroff;
register short newattr;
register short i;
register unsigned char inpskip;
if (!cp->fmtscrn) { /* unformatted screen */
if (cp->insmode || cp->inschar) if (cinsert(cp)) { /* if insert, make room */
kerr(1, cp);
if (paste) cp->pastebeep = 1; /* error if no room */
else beep(cp);
cp->apikberr = sendInsErr;
return;
}
newattr = (cp->atrbuff)[cp->curadr] & 0xbf00;
if (geflag) newattr |= 0x4000;
newchar(cp->curadr, val, newattr, 0, cp);
if (!paste) newwrite(cp);
cp->curadr++;
if (cp->curadr == cp->maxcnt) cp->curadr = 0;
if (!paste) newcur(cp);
kerr(0, cp);
return;
}
/* else formatted screen */
if ((cp->atrbuff)[cp->curadr] & 0x8000) { /* cursor on attribute byte */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendAttrErr;
return;
}
attroff = getattr(cp->curadr, cp);
if ((cp->atrbuff)[attroff] & 0x2000) { /* protected */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendProtErr;
return;
}
if (cp->insmode || cp->inschar) if (cinsert(cp)) { /* if insert, make room */
kerr(1, cp);
if (paste) cp->pastebeep = 1; /* error if no room */
else beep(cp);
cp->apikberr = sendInsErr;
return;
}
newattr = (cp->atrbuff)[cp->curadr] & 0xbf00; /* update buffer and display */
if (geflag) newattr |= 0x4000;
newchar(cp->curadr, val, newattr, (cp->atrbuff)[attroff], cp);
if (!paste) newwrite(cp);
(cp->atrbuff)[attroff] |= 0x0100; /* set MDT bit */
inpskip = 0;
for (i=0; i < cp->maxcnt; i++) { /* find next character position */
cp->curadr++;
if (cp->curadr == cp->maxcnt) cp->curadr = 0;
if ((cp->atrbuff)[cp->curadr] & 0x8000) {
/* after auto-skip, must find next unprotected field */
if (inpskip) inpskip = ((cp->atrbuff)[cp->curadr] & 0x2000) != 0;
else inpskip = ((cp->atrbuff)[cp->curadr] & 0x3000) == 0x3000;
continue;
}
if (inpskip == 0) break;
}
if (!paste) newcur(cp);
kerr(0, cp);
}
void attnkey(unsigned char val, char paste, cnr *cp)
{
short attroff, i;
cp->rdaid = val; /* save aid code for read buffer */
if ((val >= 0x6b) && (val <= 0x6e)) { /* handle short read */
if (val == 0x6d) { /* CLEAR erases screen */
clrscn(cp);
invldscr(cp);
}
if (cp->insmode && cp->cs.insreset) {
cp->insmode = 0;
newstat(cp);
}
cp->readbuff[0] = 0xd7;
cp->readbuff[5] = val;
cp->rbsize = 6;
if (cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
cp->readbuff[cp->rbsize++] = EOR;
}
senddata(1, cp);
return;
}
if (val == 0xf0) { /* test request read */
if (cp->insmode && cp->cs.insreset) {
cp->insmode = 0;
newstat(cp);
}
cp->readbuff[0] = 0xd7;
cp->readbuff[5] = 0x01;
cp->readbuff[6] = 0x6c;
cp->readbuff[7] = 0x61;
cp->readbuff[8] = 0x02;
cp->rbsize = 9;
rdmod(0, cp); /* append modified data */
return;
}
if (val == 0x7e) { /* cursor select */
if (!cp->fmtscrn) {
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendAIDErr;
return;
}
attroff = getattr(cp->curadr, cp);
i = (cp->atrbuff)[attroff] & 0x0c00;
if ((i == 0) || (i == 0x0c00)) {
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendAIDErr;
return;
}
i = attroff + 1;
if (i == cp->maxcnt) {
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendAIDErr;
return;
}
switch((cp->chrbuff)[i]) {
case 0x00: /* space and null */
case 0x40:
break;
case 0x50: /* ampersand */
val = 0x7d;
break;
case 0x6f: /* question mark */
newchar(i, 0x6e, (cp->atrbuff)[i] & 0xbf00,
(cp->atrbuff)[attroff], cp);
newwrite(cp);
(cp->atrbuff)[attroff] |= 0x0100; /* set MDT */
kerr(0, cp);
return;
case 0x6e: /* greater than */
newchar(i, 0x6f, (cp->atrbuff)[i] & 0xbf00,
(cp->atrbuff)[attroff], cp);
newwrite(cp);
(cp->atrbuff)[attroff] &= 0xfeff; /* reset MDT */
kerr(0, cp);
return;
default:
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendAIDErr;
return;
}
kerr(0, cp);
}
/* normal read-modified */
if (cp->insmode && cp->cs.insreset) {
cp->insmode = 0;
newstat(cp);
}
rdmcmd(val, cp);
}
void rdmcmd(unsigned char val, cnr *cp) /* read-modified issued */
{
char lp_read;
unsigned char addrbuff[2];
short copylen;
lp_read = (val == 0x7e);
cp->readbuff[0] = 0xd7;
cp->readbuff[5] = val;
cp->rbsize = 6;
if ((val == IAC) && cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
}
/* append two-byte cursor address */
ebcaddr(addrbuff, cp->curadr, cp);
copylen = 2;
tcpmemcpy(cp->readbuff+cp->rbsize, addrbuff, ©len, cp->tcpflg);
cp->rbsize += copylen; /* append modified data */
rdmod(lp_read, cp);
}
void rdmacmd(unsigned char val, cnr *cp) /* read-modified all issued */
{
unsigned char addrbuff[2];
short copylen;
cp->readbuff[0] = 0xd7;
cp->readbuff[5] = val;
cp->rbsize = 6;
if ((val == IAC) && cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
}
/* append two-byte cursor address */
ebcaddr(addrbuff, cp->curadr, cp);
copylen = 2;
tcpmemcpy(cp->readbuff+cp->rbsize, addrbuff, ©len, cp->tcpflg);
cp->rbsize += copylen; /* append modified data */
rdmod(0, cp);
}
void funckey(unsigned char val, char paste, cnr *cp)
{
register unsigned char prot;
register short a, attroff, b, chroff, i, next;
switch(val) {
case 1: cp->curadr -= cp->scrhsize; /* up */
if (cp->curadr < 0) cp->curadr += cp->maxcnt;
newcur(cp);
break;
case 2: cp->curadr += cp->scrhsize; /* down */
if (cp->curadr > cp->maxoff) cp->curadr -= cp->maxcnt;
newcur(cp);
break;
case 3: cp->curadr--; /* left */
if (cp->curadr < 0) cp->curadr = cp->maxoff;
newcur(cp);
break;
case 4: cp->curadr++; /* right */
if (cp->curadr > cp->maxoff) cp->curadr = 0;
newcur(cp);
break;
case 5: if (!cp->fmtscrn) { /* tab */
cp->curadr = 0;
newcur(cp);
return;
}
if ((cp->atrbuff)[cp->curadr] & 0x8000) /* initial prot value */
prot = ((cp->atrbuff)[cp->curadr] & 0x2000) != 0;
else prot = 1;
a = cp->curadr + 1;
if (a == cp->maxcnt) a = 0; /* loop from next position */
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000)
prot = ((cp->atrbuff)[a] & 0x2000) != 0;
else if (!prot) {
cp->curadr = a;
newcur(cp);
return;
}
a++;
if (a == cp->maxcnt) a = 0;
}
cp->curadr = 0;
newcur(cp);
break;
case 6: if (!cp->fmtscrn) { /* backtab */
cp->curadr = 0;
newcur(cp);
return;
}
a = cp->curadr - 1; /* start at previous position */
if (a < 0) a = cp->maxoff;
chroff = -1; /* no character yet */
for (i=0; i <= cp->maxcnt; i++) { /* find unprotected character */
if ((cp->atrbuff)[a] & 0x8000) { /* attribute */
if ((cp->atrbuff)[a] & 0x2000) chroff = -1;
else if (chroff > 0) {
cp->curadr = chroff;
newcur(cp);
return;
}
}
else chroff = a;
a--;
if (a < 0) a = cp->maxoff;
}
cp->curadr = 0;
newcur(cp);
break;
case 7: if (!cp->fmtscrn) { /* newline */
cp->curadr = ((cp->curadr / cp->scrhsize) + 1) * cp->scrhsize;
if (cp->curadr == cp->maxcnt) cp->curadr = 0;
newcur(cp);
return;
}
a = ((cp->curadr / cp->scrhsize) + 1) * cp->scrhsize;
if (a == cp->maxcnt) a = 0;
if (!((cp->atrbuff)[a] & 0x8000)) /* set prot for first char. */
prot = ((cp->atrbuff)[getattr(a, cp)] & 0x2000) != 0;
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000) prot = ((cp->atrbuff)[a] & 0x2000) != 0;
else if (!prot) {
cp->curadr = a;
newcur(cp);
return;
}
a++;
if (a == cp->maxcnt) a = 0;
}
cp->curadr = 0;
newcur(cp);
break;
case 8: if (!cp->fmtscrn) { /* home */
cp->curadr = 0;
newcur(cp);
return;
}
a = 0;
if (!((cp->atrbuff)[a] & 0x8000)) /* set prot for first char. */
prot = ((cp->atrbuff)[getattr(a, cp)] & 0x2000) != 0;
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000) prot = ((cp->atrbuff)[a] & 0x2000) != 0;
else if (!prot) {
cp->curadr = a;
newcur(cp);
return;
}
a++;
if (a == cp->maxcnt) a = 0;
}
cp->curadr = 0;
newcur(cp);
break;
case 9: /* erase eof */
if (!cp->fmtscrn) { /* unformatted screen */
for (a=cp->curadr; a < cp->maxcnt; a++) {
newchar(a, 0x00, 0, 0, cp);
}
newwrite(cp);
kerr(0, cp);
break;
}
/* else formatted screen */
if ((cp->atrbuff)[cp->curadr] & 0x8000) { /* cursor on attribute byte */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendAttrErr;
return;
}
attroff = getattr(cp->curadr, cp);
if ((cp->atrbuff)[attroff] & 0x2000) { /* protected */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
cp->apikberr = sendProtErr;
return;
}
a = cp->curadr; /* loop to store nulls */
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000) break; /* stop at attribute */
newchar(a, 0x00, 0, (cp->atrbuff)[attroff], cp);
a++;
if (a == cp->maxcnt) a = 0;
}
newwrite(cp);
(cp->atrbuff)[attroff] |= 0x0100; /* set MDT bit */
kerr(0, cp);
break;
case 10: if (!cp->fmtscrn) { /* erase input */
clrscn(cp);
invldscr(cp);
return;
}
b = 9999;
a = firstattr(cp); /* start at first attribute */
attroff = 0;
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000) { /* attribute */
prot = ((cp->atrbuff)[a] & 0x2000) != 0;
if (!prot) (cp->atrbuff)[a] &= 0xfeff; /* reset MDT */
attroff = a; /* save attribute offset */
}
else if (!prot) { /* character */
newchar(a, 0x00, 0, (cp->atrbuff)[attroff], cp);
if (a < b) b = a; /* save first character */
}
a++;
if (a == cp->maxcnt) a = 0;
}
newwrite(cp);
if (b < 9999) cp->curadr = b;
else cp->curadr = 0;
newcur(cp);
break;
case 11: cp->insmode ^= 1; /* toggle insert mode */
newstat(cp);
break;
case 12: if (cp->fmtscrn) { /* delete character */
if ((cp->atrbuff)[cp->curadr] & 0x8000) { /* cursor on attribute byte */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
return;
}
i = (cp->atrbuff)[attroff = getattr(cp->curadr, cp)];
if (i & 0x2000) { /* protected */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
return;
}
}
else i = 0;
a = cp->curadr; /* first location to change */
/* calculate last location to change */
if (cp->cs.repnull && cp->fmtscrn) {
if (a > 0) b = a - 1;
else b = cp->maxoff;
}
else {
b = ((cp->curadr / cp->scrhsize) + 1) * cp->scrhsize - 1; /* last loc. on line */
}
while (a != b) {
next = a+1;
if (next == cp->maxcnt) next = 0;
if ((cp->atrbuff)[next] & 0x8000) break;
else {
newchar(a, (cp->chrbuff)[next], (cp->atrbuff)[next], i, cp);
a = next;
}
}
newchar(a, 0x00, 0, i, cp);
newwrite(cp);
if (cp->fmtscrn) (cp->atrbuff)[attroff] |= 0x0100; /* set MDT bit */
kerr(0, cp);
break;
case 13: cp->kb_err = cp->kblock = cp->kblcode = cp->insmode = 0; /* reset */
cp->kbqsize = 0;
newstat(cp);
break;
case 14: if (!cp->fmtscrn) { /* dup */
if (cp->insmode) if (cinsert(cp)) { /* if insert, make room */
kerr(1, cp);
if (paste) cp->pastebeep = 1; /* error if no room */
else beep(cp);
return;
}
b = (cp->atrbuff)[cp->curadr] & 0xbf00;
newchar(cp->curadr, 0x1c, b, 0, cp);
newwrite(cp);
cp->curadr = 0;
newcur(cp);
kerr(0, cp);
return;
}
/* else formatted screen */
if ((cp->atrbuff)[cp->curadr] & 0x8000) { /* cursor on attribute byte */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
return;
}
attroff = getattr(cp->curadr, cp);
if ((cp->atrbuff)[attroff] & 0x2000) { /* protected */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
return;
}
if (cp->insmode) if (cinsert(cp)) { /* if insert, make room */
kerr(1, cp);
if (paste) cp->pastebeep = 1; /* error if no room */
else beep(cp);
return;
}
b = (cp->atrbuff)[cp->curadr] & 0xbf00; /* update buffer and display */
newchar(cp->curadr, 0x1c, b, (cp->atrbuff)[attroff], cp);
newwrite(cp);
(cp->atrbuff)[attroff] |= 0x0100; /* set MDT bit */
kerr(0, cp);
prot = 1;
a = cp->curadr + 1;
if (a == cp->maxcnt) a = 0; /* loop from next position */
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000)
prot = ((cp->atrbuff)[a] & 0x2000) != 0;
else if (!prot) {
cp->curadr = a;
newcur(cp);
return;
}
a++;
if (a == cp->maxcnt) a = 0;
}
cp->curadr = 0;
newcur(cp);
break;
case 15: datakey(0x1e, 0, paste, cp); /* field mark */
break;
case 16: cp->aplmode ^= 1; /* toggle APL mode */
cp->fixbracket = cp->cs.std_brack && (!cp->aplmode) && (cp->stdfont != ALAFONT);
newstat(cp);
break;
case 17: /* insert blank */
a = cp->curadr;
cp->inschar = 1;
datakey(0x40, 0, paste, cp);
cp->inschar = 0;
cp->curadr = a;
newcur(cp);
break;
case 18: /* rub out (non-std) */
a = cp->curadr; /* get previous location */
a--;
if (a < 0) a = cp->maxoff;
if (cp->fmtscrn) {
if ((cp->atrbuff)[a] & 0x8000) { /* attribute byte */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
return;
}
attroff = getattr(a, cp);
if ((cp->atrbuff)[attroff] & 0x2000) { /* protected */
kerr(2, cp);
if (paste) cp->pastebeep = 1;
else beep(cp);
return;
}
}
cp->curadr = a;
datakey(0x00, 0, paste, cp);
cp->curadr = a;
newcur(cp);
break;
case 19: cp->curadr -= cp->scrhsize * 2; /* up*2 */
if (cp->curadr < 0) cp->curadr += cp->maxcnt;
newcur(cp);
break;
case 20: cp->curadr += cp->scrhsize * 2; /* down */
if (cp->curadr > cp->maxoff) cp->curadr -= cp->maxcnt;
newcur(cp);
break;
case 21: cp->curadr-=2; /* left */
if (cp->curadr < 0) cp->curadr += cp->maxcnt;
newcur(cp);
break;
case 22: cp->curadr+=2; /* right */
if (cp->curadr > cp->maxoff) cp->curadr -=cp->maxcnt;
newcur(cp);
break;
case 23: cp->cs.curpos ^= 1; /* cursor position */
newstat(cp);
break;
default:
cp->apikberr = sendOpErr;
break;
}
}
short getattr(short offset, cnr *cp)
{
register short i;
short nextoffset;
/* just return result if already at an attribute */
if ((cp->atrbuff)[offset] & 0x8000) {
cp->savedvalid = 1;
cp->savedoffset = offset;
cp->savedattr = offset;
return(offset);
}
/* check if we already know the result from the last time */
if (cp->savedvalid) {
nextoffset = cp->savedoffset + 1;
if (nextoffset == cp->maxcnt) nextoffset = 0;
if (nextoffset == offset) {
cp->savedoffset = nextoffset;
return(cp->savedattr);
}
}
/* scan backwards to find the attribute */
if (offset == 0) offset = cp->maxoff;
else offset--;
for (i=0; i < cp->maxoff; i++) {
if ((cp->atrbuff)[offset] & 0x8000) {
cp->savedvalid = 1;
cp->savedoffset = offset;
cp->savedattr = offset;
return(offset);
}
if (offset == 0) offset = cp->maxoff;
else offset--;
}
return(offset); /* shouldn't be called this way */
}
short firstattr(cnr *cp)
{
register short i;
for (i=0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[i] & 0x8000) return(i);
}
return(0); /* return 0 if no attributes (shouldn't be called this way) */
}
void rdmod(char lp_read, cnr *cp)
{
register unsigned short i, offset, j, k;
register unsigned char c, mod;
char modwrap; /* true if last modified field may wrap */
unsigned char addrbuff[2];
short copylen;
if (cp->cs.repnull) nullreplace(cp);
if (!cp->fmtscrn) {
for (i=0; i < cp->maxcnt; i++) {
if ((c = (cp->chrbuff)[i]) == 0) continue;
if (cp->rbsize > (cp->rballoc-4)) {
if (cp->tcpflg) {
senddata(1, cp);
cp->rbsize = 5;
}
else {
break;
}
}
if ((cp->atrbuff)[i] & 0x4000)
if (!(((c == 0xad) || (c == 0xbd)) && cp->fixbracket))
cp->readbuff[cp->rbsize++] = 0x08;
cp->readbuff[cp->rbsize++] = c;
if ((c == IAC) && cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
}
}
cp->bufadr = 0;
if (cp->tcpflg) addeor(cp);
senddata(1, cp);
return;
}
offset=firstattr(cp);
for (i=0; i < cp->maxcnt; i++) {
k = (cp->atrbuff)[offset];
if (k & 0x8000) { /* handle attribute byte */
mod = 0;
modwrap = 0;
if (k & 0x0100) { /* MDT bit set */
if (!lp_read) {
mod = 1;
}
modwrap = 1;
j = offset+1;
if (j > cp->maxoff) j = 0;
if ((cp->rbsize > (cp->rballoc-6)) && cp->tcpflg) {
senddata(1, cp);
cp->rbsize = 5;
}
if (cp->rbsize <= (cp->rballoc-6)) {
cp->readbuff[cp->rbsize++] = 0x11;
ebcaddr(addrbuff, j, cp); /* store 2-byte address */
copylen = 2;
tcpmemcpy(cp->readbuff+cp->rbsize, addrbuff, ©len,
cp->tcpflg);
cp->rbsize += copylen;
}
}
}
else if (mod) { /* handle data byte in modified field */
if ((c = (cp->chrbuff)[offset]) != 0) {
if ((cp->rbsize > (cp->rballoc-4)) && cp->tcpflg) {
senddata(1, cp);
cp->rbsize = 5;
}
if (cp->rbsize <= (cp->rballoc-4)) {
if (k & 0x4000) {
if (!(((c == 0xad) || (c == 0xbd)) && cp->fixbracket)) {
cp->readbuff[cp->rbsize++] = 0x08;
}
}
cp->readbuff[cp->rbsize++] = c;
if ((c == IAC) && cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
}
}
}
}
offset++;
if (offset > cp->maxoff) offset = 0;
}
cp->bufadr = 0;
/* change buffer address if last modified field wraps */
if (modwrap && (offset != 0)) cp->bufadr = offset;
if (cp->tcpflg) addeor(cp);
senddata(1, cp);
}
void rdbuff(cnr *cp) /* read buffer */
{
register short i;
register unsigned char c, atrbyte;
unsigned char addrbuff[2];
short copylen;
cp->readbuff[0] = 0xc2;
cp->readbuff[5] = cp->rdaid;
cp->rbsize = 6;
if ((cp->rdaid == IAC) && cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
}
/* append two-byte cursor address */
ebcaddr(addrbuff, cp->curadr, cp);
copylen = 2;
tcpmemcpy(cp->readbuff+cp->rbsize, addrbuff, ©len, cp->tcpflg);
cp->rbsize += copylen;
if (cp->cs.repnull) nullreplace(cp);
for (i=0; i < cp->maxcnt; i++) {
if (cp->rbsize > (cp->rballoc-4)) {
if (cp->tcpflg) {
senddata(0, cp);
cp->rbsize = 5;
}
else {
break;
}
}
if ((cp->atrbuff)[i] & 0x8000) { /* attribute byte */
cp->readbuff[cp->rbsize++] = 0x1d; /* start field */
atrbyte = ((cp->atrbuff)[i] >> 8) & 0x3f;
cp->readbuff[cp->rbsize++] = ebc64[atrbyte]; /* attribute */
}
else {
c = (cp->chrbuff)[i];
if ((cp->atrbuff)[i] & 0x4000)
if (!(((c == 0xad) || (c == 0xbd)) && cp->fixbracket))
cp->readbuff[cp->rbsize++] = 0x08;
cp->readbuff[cp->rbsize++] = c;
if ((c == IAC) && cp->tcpflg) {
cp->readbuff[cp->rbsize++] = IAC;
}
}
}
cp->bufadr = 0;
if (cp->tcpflg) addeor(cp);
senddata(0, cp);
}
void addeor(cnr *cp)
{
if (cp->rbsize > (cp->rballoc-3)) {
senddata(1, cp);
cp->rbsize = 5;
}
cp->readbuff[cp->rbsize++] = IAC;
cp->readbuff[cp->rbsize++] = EOR;
}
short cinsert(cnr *cp)
{
register unsigned char t;
register short a, b, c, i, n;
b = c = n = -1; /* -1 = no blank, character or null found */
a = cp->curadr; /* scan to end of field or all bytes */
for (i = 0; i < cp->maxcnt; i++) {
if ((cp->atrbuff)[a] & 0x8000) break; /* stop at attribute byte */
t = (cp->chrbuff)[a]; /* get charcter value */
/* do null to blank conversion if wanted */
if ((t == 0x00) && cp->cs.repnull) t = 0x40;
if (t == 0x00) { /* found null */
n = a; /* remember where */
break; /* done now */
}
if (t == 0x40) b = i; /* remember last blank */
else c = i; /* remember last character */
a++;
if (a == cp->maxcnt) a = 0;
}
if (n >= 0) a = n; /* use null if found */
else if ((b > c) && cp->cs.impnull) { /* else use trailing blank */
a = cp->curadr + b; /* (non-standard */
if (a > cp->maxoff) a -= cp->maxcnt;
}
else return(1); /* else return error */
if (cp->fmtscrn) i = (cp->atrbuff)[getattr(cp->curadr, cp)];
else i = 0;
while (a != cp->curadr) { /* loop to shift bytes right */
b = a-1; /* get previous offset */
if (b < 0) b = cp->maxoff;
newchar(a, (cp->chrbuff)[b], (cp->atrbuff)[b], i, cp); /* define new values */
a--;
if (a < 0) a = cp->maxoff;
}
return(0);
}
void nullreplace(cnr *cp)
{
register unsigned short i, offset, nullcount, a;
register unsigned char mod;
unsigned char *firstnull;
if (!cp->fmtscrn) {
nullcount = 0;
for (i=0; i < cp->maxcnt; i++) {
if ((cp->chrbuff)[i] == 0) {
if (nullcount == 0) firstnull = cp->chrbuff+i;
nullcount++;
}
else {
while (nullcount > 0) {
(*firstnull) = 0x40;
firstnull++;
nullcount--;
}
}
}
return;
}
offset=firstattr(cp);
for (i=0; i < cp->maxcnt; i++) {
a = (cp->atrbuff)[offset];
if (a & 0x8000) { /* handle attribute byte */
mod = 0;
if (a & 0x0100) { /* MDT bit set */
mod = 1;
nullcount = 0;
}
}
else if (mod) { /* handle data byte in modified field */
if ((cp->chrbuff)[offset] == 0) {
if (nullcount == 0) firstnull = cp->chrbuff+offset;
nullcount++;
}
else {
while (nullcount > 0) {
(*firstnull) = 0x40;
firstnull++;
nullcount--;
}
}
}
offset++;
if (offset > cp->maxoff) offset = 0;
}
}
void senddata(char lockflag, cnr *cp)
{
cp->kb_err = 0;
if (cp->tcpflg) {
if (lockflag) {
cp->kblock = 1;
cp->kblcode = 2;
}
tcpwrite(cp->readbuff+5, cp->rbsize-5, cp);
return;
}
if (cp->serflg) {
cp->readbuff[1] = cp->readbuff[2] = 0;
serattn(cp);
if (lockflag) {
cp->kblock = 1;
cp->kblcode = 2;
newstat(cp);
}
return;
}
if (lockflag) {
cp->kblock = 1;
cp->kblcode = 2;
}
sawrite(cp->readbuff+5, cp->rbsize-5, cp);
}
void kerr(short code, cnr *cp)
{
if (code == cp->kb_err) return;
cp->kb_err = code;
newstat(cp);
}
void kbnew(unsigned char chr, cnr *cp)
{
register unsigned char c, typ, val;
c = chr; /* get character */
/* define type, value for key */
typ = kbtyp[c] & 0x3f;
if (cp->aplmode) val = kbapl[c];
else val = kbstd[c];
/* check for Enter or CLEAR to start new session */
if ((typ == 2) && ((val == 0x6d) || (val == 0x7d))) {
if (cp->serflg) serlgin(cp);
else if (cp->tcpflg) tcplgin(cp);
else salgin(cp);
return;
}
beep(cp);
}
void ebcaddr(unsigned char *buf, unsigned short addr, cnr *cp)
{
if (cp->addr14 && cp->ewamode) { /* generate 14-bit address */
buf[0] = addr/256;
buf[0] &= 0x3f;
buf[1] = addr%256;
}
else { /* generate 12-bit address */
buf[0] = ebc64[addr/64];
buf[1] = ebc64[addr%64];
}
}